#include <ArduinoJson.h>

#include <DHTesp.h>

#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include <ESP8266WebServer.h>



String ssid = "TXG";
String password = "123123123";


int DHTPIN = 4;
DHTesp dht;

ESP8266WebServer server(80);


int ledRed = 2;
void ledOn() {
  digitalWrite(ledRed, LOW  ); // Turn the LED on (Note that LOW is the voltage level
}

void ledOff() {
  digitalWrite(ledRed, HIGH );  // Turn the LED off by making the voltage HIGH
}

void ledToggle() {
  digitalWrite(ledRed, !digitalRead(ledRed));  // Change the state of the LED
}

#define DEBUG 1

const char DS_Temp[] = "TEMP";                        // 数据流 温度TEMP -- Stream "TEMP"
const char DS_Hum[] = "HUMI";
const char OneNetServer[] = "api.heclouds.com";
const char APIKEY[] = "xxxxxxx";

int led0 = 0;
String ledIsSS = "no";


WiFiClient client;
void postData(int dId, float val_t, float val_h)
{
  // 创建发送请求的URL -- We now create a URI for the request
  String url = "/devices/";
  url += String(dId);
  url += "/datapoints?type=3";
  String data = "{\"" + String(DS_Temp) + "\":" + String(val_t) + ",\"" +
                String(DS_Hum) + "\":" + String(val_h) + "}";
  // 创建发送指令 -- We now combine the request to the server
  String post_data = "POST " + url + " HTTP/1.1\r\n" +
                     "api-key:" + APIKEY + "\r\n" +
                     "Host:" + OneNetServer + "\r\n" +
                     "Content-Length: " + String(data.length()) + "\r\n" +                     //发送数据长度
                     "Connection: close\r\n\r\n" +
                     data;

  // 发送指令 -- This will send the request to server
  client.print(post_data);
  // 调试模式串口打印发送的指令 -- The request will be printed if we choose the DEBUG mode
  if (DEBUG)
  {
    Serial.println(post_data);
  }
  unsigned long timeout = millis();
  while (client.available() == 0)
  {
    if (millis() - timeout > 2000)
    {
      Serial.println(">>> Client Timeout !");
      client.stop();
      return;
    }
  }
}



String localip_to_String()//获取UDP 广播地址
{
  IPAddress ip;
  int buf[4];
    ip = WiFi.localIP();
  for (int i = 0; i < 4; i++)
  {
    buf[i] = ip[i];
  }
  String temp = "";
  temp += String(buf[0]);
  temp += '.';
  temp += String(buf[1]);
  temp += '.';
  temp += String(buf[2]);
  temp += '.';
  temp += String(buf[3]);
  return temp;
}

int dht11pin = 4;

void restartWifi() {
  WiFi.begin(ssid, password);
  delay(3000);
  if (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("Connection Failed! Rebooting...");
    WiFi.begin("JK", "jk123456");
    delay(3000);
   
  }
}
void handleNotFound() {

  String message = "File Not Found\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += (server.method() == HTTP_GET) ? "GET" : "POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";
  for (uint8_t i = 0; i < server.args(); i++) {
    message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
  }
  server.send(404, "text/plain", message);
}
void handleRoot() {
  String str = "<!DOCTYPE html><html><head><meta charset='UTF-8'>";
  str = str + "</head><body><h1>hello from esp8266!  ";
  str = str + "<br/><a href='/up'>固件更新</a> <span>,</span>";
  str = str + " <a href='/inline'>控制中心</a>";
  str = str + "<br/>内网ip: " +  localip_to_String()  ;
  str = str + "</h1></body></html> ";

  server.send(200, "text/html", str);
}
void inlineWifi() {
    String inlineUrl = "/inline";
    String ledargName = "led";
    //开灯关灯控制
    String ledarg = server.arg(ledargName);
    if ( server.arg(ledargName) == "on" ) {
      ledIsSS = "no";
      ledOn();
    }

    if ( server.arg(ledargName) == "off" ) {
      //if(strcmp( "off" , ledarg ) ){
      ledIsSS = "no";
      ledOff();
    }

    if ( server.arg(ledargName) == "scintillating" ) {
      //if(strcmp( "scintillating" , ledarg ) ){
      ledIsSS = "yes";
      ledOff();
    }

    if (server.hasArg("wifiid") && server.hasArg("wifipwd")) {
      ssid = server.arg("wifiid");
      password = server.arg("wifipwd");
      Serial.print("ssid: ");
      Serial.print(ssid);
      Serial.print(" , password: ");
      Serial.println(password);
      WiFi.begin( ssid, password );

      //ESP.restart();
      //restartWifi();
      Serial.println(" WebConfilg Ok");
      Serial.print("IP address: ");
      Serial.println(WiFi.localIP());
    }

    char buffer[10];
    String shiString = dtostrf(dht.getHumidity(), 4, 1, buffer);
    String wenString = dtostrf(dht.getTemperature(), 4, 1, buffer);
    String str = "<!DOCTYPE html><html><head><meta charset='UTF-8'></head><body>";
    str = str + "<h1>湿度: " + shiString + " 温度: " + wenString ;
    //内网IP
    str = str + "<br/>内网ip: " +  localip_to_String()  ;
    str = str + "<br/>红色LED <a href='" + inlineUrl + "?" + ledargName + "=on'> 常亮 </a> <span>,</span>";
    str = str + " <a href='" + inlineUrl + "?" + ledargName + "=off'> 常灭 </a> <span>,</span>";
    str = str + " <a href='" + inlineUrl + "?" + ledargName + "=scintillating'> SOS </a> ";
    str = str + "<br/><form method='POST' action='" + inlineUrl + "'>";
    str = str + " WIFI <input type='wifiid' name='wifiid' placeholder='名称'>";
    str = str + "<input type='text' name='wifipwd' placeholder='密码'>";
    str = str + "<input type='submit' value='连接'></form></h1></body></html>";
    server.send(200, "text/html", str);
  }

void setup() {
  dht.setup(DHTPIN, DHTesp::DHT11);
  WiFi.mode(WIFI_AP_STA);               //设置工作模式 -- set work mode:  WIFI_AP /WIFI_STA /WIFI_AP_STA

  pinMode(ledRed, OUTPUT);
  ledOn();

  Serial.begin(115200);

  restartWifi();
 
  
  Serial.println("Ready");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  server.on("/", handleRoot);

  String inlineUrl = "/inline";
  server.on(inlineUrl, inlineWifi);

  server.on("/up", HTTP_GET, []() {
    server.sendHeader("Connection", "close");
    String serverIndex = "<!DOCTYPE html><html><head><meta charset='UTF-8'></head>";
    serverIndex = serverIndex + "<body><form method='POST' action='/update' enctype='multipart/form-data'>";
    serverIndex = serverIndex + "<input type='file' name='update'><input type='submit' value='上传'>";
    serverIndex = serverIndex + "</form></body></html>";
    server.send(200, "text/html", serverIndex);
  });

  server.on("/update", HTTP_POST, []() {
    server.sendHeader("Connection", "close");
    server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK");
    ESP.restart();
  }, []() {
    HTTPUpload& upload = server.upload();
    if (upload.status == UPLOAD_FILE_START) {
      Serial.setDebugOutput(true);
      WiFiUDP::stopAll();
      Serial.printf("Update: %s\n", upload.filename.c_str());
      uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
      if (!Update.begin(maxSketchSpace)) { //start with max available size
        Update.printError(Serial);
      }
    } else if (upload.status == UPLOAD_FILE_WRITE) {
      if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
        Update.printError(Serial);
      }
    } else if (upload.status == UPLOAD_FILE_END) {
      if (Update.end(true)) { //true to set the size to the current progress
        Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize);
      } else {
        Update.printError(Serial);
      }
      Serial.setDebugOutput(false);
    }
    yield();
  });

  server.onNotFound(handleNotFound);

  server.begin();
  Serial.println("HTTP server started");

}

void ledfor(String type ){
  String yes="yes";
  String value="long";
  int a = 1;
     /* while 循环执行 */
     while( a <=1 ){
      if(ledIsSS != yes){
        break;
      }
        a++;
        ledOff();
        delay(1000);
        ledOn();
        if ( value  == type ) {
          delay(1000);
        }else{
          delay(100);
        }
        
     }
}
void demoHandle(){
  server.handleClient();
  ArduinoOTA.handle();
}
void loop() {
  String yes="yes";
  demoHandle();
  if ( ledIsSS  == yes ) {
//if(strcmp(ledIsSS , "yes" ) ){
    ledfor("sort");
    demoHandle();
    ledfor("long");
    demoHandle();
    ledfor("sort");
    demoHandle();
    if ( ledIsSS  == yes ) {
      ledOff();
      delay(1000);
    }
    
  }

}
